/* 
 * File:   parentChildComm.cpp
 * Author: Stephen Durfey and Steve Gal
 *
 * Created on September 20, 2008, 11:09 AM
 */

#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <cstdlib>
#include <stdlib.h>
#include "semaphore.h"

using namespace std;


int main(int argc, char** argv) 
{
      //0 is parent, 1 is child
      Semaphore semaphoreComm(55,2);
      semaphoreComm.Init(0, 1);
      semaphoreComm.Init(1, 0);
      int randNum = atoi(argv[1]), exit_status;
      string procOrder = argv[2];
      
      pid_t child;      //holds the child process ID
      
      srand(NULL); //seeds random generator
      
      child = fork();
         
         if(child != -1)   //checks to make sure the fork worked
         {
            if(child == 0)  //child process
            {
                if(procOrder == "parent")
                {
                               
                    while(randNum > 0)
                    {
                        semaphoreComm.Wait(1);  
                        cout << "Child: " << getpid() << endl;
                        semaphoreComm.Signal(0);
                     
                        randNum--;
                    }
                }
                else
                {
                    while(randNum > 0)
                    {
                        semaphoreComm.Wait(0);
                        cout << "Child: " << getpid() << endl;
                        semaphoreComm.Signal(1);
                        randNum--;
                    }
                }
                
                exit(1);
             }
             else
             {
                 if(procOrder == "parent")
                 {
                 
                    while(randNum > 0)
                    {
                        semaphoreComm.Wait(0);
                        cout << "Parent: " << getpid() << endl;
                        semaphoreComm.Signal(1);
                        randNum--;
                    }
                 }
                 else
                 {
                     while(randNum > 0)
                     {
                        semaphoreComm.Wait(1);
                        cout << "Parent: " << getpid() << endl;
                        semaphoreComm.Signal(0);
                        randNum--;
                     }
                     
                 }
             }
          }
         else
             cerr << "didnt fork\n";
      
      //if wait() is not used here, and the parent process is to go first
      //the semaphore will be destroyed before the child has a chance to print
      //out last line. 
     
      wait(&exit_status); 
      semaphoreComm.Destroy();
      
      
      return (EXIT_SUCCESS);
}

